package com.evangelion.core.controller;

import com.evangelion.core.bean.*;
import com.evangelion.core.pojo.AlumnoClassPractica;
import com.evangelion.core.service.AlumnoService;
import com.evangelion.core.service.FacturaAlumnoService;
import com.evangelion.core.utils.MensajesFace;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.commons.collections.CollectionUtils;
import org.primefaces.context.RequestContext;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import java.io.*;
import java.sql.Connection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Kellycasma
 */
@ManagedBean
@ViewScoped
public class AlumnoController extends MensajesFace implements Serializable {

    private Alumno alumno;

    private String valorBusqueda;
    private Date diffFecha;
    private LazyDataModel<Alumno> listaAlumno;
    private Permisomatriculado permisomatriculado;
    private Permisoposee permisoposee;
    private DefaultStreamedContent dc;
    private DefaultStreamedContent dcContract;
    boolean todo;
    private String pdfImprimir;
    private AlumnoClassPractica alumnoClassPractica;
    @ManagedProperty(value = "#{facturaAlumnoController}")
    private FacturaAlumnoController fac;

    @PostConstruct
    @Override
    public void init() {
        super.init();

        alumno = new Alumno();
        alumno.setDatossolicitud(new Datossolicitud());
        alumno.setPermisomatriculadoList(new ArrayList<Permisomatriculado>());
        alumno.setPermisoposeeList(new ArrayList<Permisoposee>());
        permisomatriculado = new Permisomatriculado();
        permisoposee = new Permisoposee();

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -10);
        diffFecha = calendar.getTime();
        pdfImprimir = "/general/blanco.pdf";
    }

    public void onTabChange(TabChangeEvent event) {
        alumnoClassPractica = new AlumnoClassPractica();
        if (event.getTab().getId().equals("tabClasesPracticas")) {
            if (null != alumno.getId()) {
                List<AlumnoClassPractica> practicaList = serviceAlunmo.findClassPracticas(alumno.getId());
                if (CollectionUtils.isNotEmpty(practicaList)) {
                    alumnoClassPractica = practicaList.get(0);
                }
            }

        }
    }

    @SuppressWarnings("serial")
    public void configDataModel() {
        listaAlumno = new LazyDataModel<Alumno>() {
            @Override
            public List<Alumno> load(int start, int max, String arg2,
                                     SortOrder arg3, Map<String, String> arg4) {
                if (valorBusqueda == null) {
                    valorBusqueda = "";
                }
                List<Alumno> listaAlu = (List) serviceAlunmo.searchByNifNombre(seccion, valorBusqueda, start, max);
                return listaAlu;
            }
        };
        listaAlumno.setRowCount(serviceAlunmo.countPage(seccion, valorBusqueda));
    }

    public void printpdf(Map parameters, String archivo, int id) {
        try {
            todo = false;
            Connection conexion = connectionUtil.getConnection();
            String urlMaster = connectionUtil.getServletContext().getRealPath(REPORT_FOLDER + archivo);
            System.out.println("urlMaster: " + urlMaster);
            JasperReport reporteMaster = null;
            try {
                reporteMaster = (JasperReport) JRLoader.loadObject(urlMaster);
            } catch (Exception e) {
                e.printStackTrace();
            }
            JasperPrint print = JasperFillManager.fillReport(reporteMaster, parameters, conexion);
            byte[] bytes = JasperExportManager.exportReportToPdf(print);

            if (bytes.length >= 1211 && bytes.length <= 1400) {
                dc = null;
            } else {
                setPdfImprimir("/general/factura_" + id + ".pdf");
                todo = true;
                InputStream stream = new ByteArrayInputStream(bytes);
                dc = new DefaultStreamedContent(stream, "application/pdf", getPdfImprimir());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void printContract() {
        try {
            String urlMaster = connectionUtil.getServletContext().getRealPath(REPORT_FOLDER + "TeachingContract.pdf");

            FileInputStream fis = new FileInputStream(new File(urlMaster));

            dcContract = new DefaultStreamedContent(fis, "application/pdf", "TeachingContract.pdf");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //    public void printContract() {
//        Map parameters = new HashMap();
//
//        try {
//
//            String page1 = connectionUtil.getServletContext().getRealPath(REPORT_FOLDER + "TeachingContract_Page_1.jasper");
//            String page2 = connectionUtil.getServletContext().getRealPath(REPORT_FOLDER + "TeachingContract_Page_2.jasper");
//
//            JasperReport page1Report = (JasperReport) JRLoader.loadObject(page1);
//            JasperReport page2Report = (JasperReport) JRLoader.loadObject(page2);
//
//            List<JasperPrint> reportsList = new ArrayList<JasperPrint>();
//
//            Connection conexion = connectionUtil.getConnection();
//
//            JasperPrint print1 = JasperFillManager.fillReport(page1Report, parameters, conexion);
//            JasperPrint print2 = JasperFillManager.fillReport(page2Report, parameters, conexion);
//
//            reportsList.add(print1);
//            reportsList.add(print2);
//
//
//            byte[] bytes = JasperExportManager.exportReportToPdf(mergeReport(reportsList));
//            //byte[] bytes = JasperExportManager.exportReportToPdf(print2);
//            InputStream stream = new ByteArrayInputStream(bytes);
//            dcContract = new DefaultStreamedContent(stream, "application/pdf", "/general/TeachingContract.pdf");
//            connectionUtil.closeConect();
//        }
//        catch (Exception ex) {
//            ex.printStackTrace();
//        }
//    }
    
    public void imprimirFacturaAlumno(int id) {
        String archivo = "resporteFacturaArenal.jasper"; //RICH:20140313-0001
        Map parameters = new HashMap();
        parameters.put("id", id);
        printpdf(parameters, archivo, id);
    }

    //    public void runReporte() {
//        try {
//
//            //String urlMaster = connectionUtil.getServletContext().getRealPath(REPORT_FOLDER + "reporteFacturaAlumno.jasper");
//            //String urlMaster = "C:/Users/Kellycasma/Desktop/Copia Seguridad/nueva carpeta/Evangelion/web/general/reportes/reporteFacturaAlumno.jasper";
//            File urlMaster = null;
//            urlMaster = new File(REPORT_FOLDER + "reporteFacturaAlumno.jasper");
//
//            System.out.println("Master " + urlMaster);
//            if (urlMaster == null) {
//                System.out.println("No se encuentra el archivo del reporte");
//            }
//            System.out.println("1");
//            JasperReport masterReport = null;
//            System.out.println("2");
//            try {
//                System.out.println("3");
//                masterReport = (JasperReport) JRLoader.loadObject(urlMaster);
//                System.out.println("4");
//            } catch (JRException e) {
//                System.out.println("Error al cargar el reporte " + e.getMessage());
//            }
//            System.out.println("5");
//            Map parametro = new HashMap();
//            System.out.println("6");
//            JasperPrint jp = JasperFillManager.fillReport(masterReport, parametro);
//            System.out.println("7");
//            JasperViewer jv = new JasperViewer(jp, false);
//            System.out.println("8");
//            jv.setTitle("Factura Reporte");
//            System.out.println("9");
//            jv.setVisible(true);
//            System.out.println("10");
//        } catch (Exception e) {
//            System.out.println("Error al generar Reporte " + e.getMessage());
//        }
//    }
    public void addPermisoMatriculado() {
        permisomatriculado.setAlumno(alumno);
        permisomatriculado.setFechaingreso(new Date());
        alumno.getPermisomatriculadoList().add(permisomatriculado);
        permisomatriculado = new Permisomatriculado();
    }

    public void addPermisoPosee() {
        permisoposee.setAlumno(alumno);
        permisoposee.setFechaingreso(new Date());
        alumno.getPermisoposeeList().add(permisoposee);
        permisoposee = new Permisoposee();
    }

    public void deletePermisoPosee(Permisoposee perpos) {
        int remover = 0;
        for (int i = 0; i < alumno.getPermisoposeeList().size(); i++) {
            if (alumno.getPermisoposeeList().get(i).getPermiso().equals(perpos.getPermiso())) {
                remover = i;
            }
        }
        alumno.getPermisoposeeList().remove(remover);
        RequestContext.getCurrentInstance().execute("loadtablapermisoposee()");

    }

    public void deletePermisoMatriculado(Permisomatriculado permatr) {
        int remover = 0;
        for (int i = 0; i < alumno.getPermisomatriculadoList().size(); i++) {
            if (alumno.getPermisomatriculadoList().get(i).getPermiso().equals(permatr.getPermiso())) {
                remover = i;
            }
        }
        alumno.getPermisomatriculadoList().remove(remover);
        RequestContext.getCurrentInstance().execute("loadtablapermisomatriculado()");

    }

    public void save() {
        if (validarForm()) {

            alumno.setCliente(usuario.getCliente());
            alumno.setSeccion(seccion);

            if (alumno.getId() == null) {
                alumno.setFechaCreacion(new Date());
            }
            alumno.setFechaActualizacion(new Date());
            serviceAlunmo.save(alumno);
            serviceAlunmo.savePermisosDS(alumno, permisomatriculado, permisoposee);
            limpiarForm();
            msgCambiosGuardados();
            init();
        }
    }

    public void limpiarForm() {
        alumno = new Alumno();
    }

    public Alumno getAlumno() {
        return alumno;
    }

    public void setAlumno(Alumno alumno) {

        System.out.println("CArgando alumno NIF Before:" + alumno.getNif());
        if (!alumno.getNif().equals("")) {
            String letra = obtenerLetraNif(alumno.getNif());
            if (letra != null) {
                alumno.setNif(alumno.getNif() + letra);
            }
        }
        System.out.println("CArgando alumno NIF After:" + alumno.getNif());
        this.alumno = alumno;

        alumnoClassPractica = new AlumnoClassPractica();

        if (null != alumno.getId()) {
            List<AlumnoClassPractica> practicaList = serviceAlunmo.findClassPracticas(alumno.getId());
            if (CollectionUtils.isNotEmpty(practicaList)) {
                alumnoClassPractica = practicaList.get(0);
            }
        }

    }

    public boolean validarForm() {
        boolean requerido = true;

        if (!validarNIF(alumno.getNif())) {
            msgValidacion("EL NIF");
            requerido = false;
        }
        try {
            Alumno alumnoTemporal = (Alumno) serviceAlunmo.findObjByParam("nif", alumno.getNif());
            if (alumnoTemporal != null) {
                if ((alumno.getId() == null || (!alumno.getId().equals(alumnoTemporal.getId()) && alumno.getId() != null))) {
                    msgValidacion("Ya existe pertenece a " + alumnoTemporal.getNombres());
                    requerido = false;
                } else {
                    if (alumno.getId() != null) {
                        alumno.setNif(alumnoTemporal.getNif());
                    }
                }
            }
            return requerido;
        } catch (Exception ex) {
            msgValidacion("Ha ocurrido un error");
            return false;
        }
    }

    public void search() {
        //    System.out.println("...valorBusqueda" + valorBusqueda);
        configDataModel();
    }

    public static String obtenerLetraNif(String numero) {
        String ret = "";
        try {
            String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
            int index = Integer.parseInt(numero);
            index = index % 23;
            ret = letras.substring(index, index + 1);
        } catch (NumberFormatException e) {
            ret = "";
        }
        return ret;
    }

    public static boolean validarNIF(String nif) {
        boolean correcto = false;
        Pattern pattern = Pattern.compile("(\\d{1,8})([TRWAGMYFPDXBNJZSQVHLCKEtrwagmyfpdxbnjzsqvhlcke])");
        Matcher matcher = pattern.matcher(nif);
        if (matcher.matches()) {
            String letra = matcher.group(2);
            String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
            int index = Integer.parseInt(matcher.group(1));
            index = index % 23;
            String reference = letras.substring(index, index + 1);

            if (reference.equalsIgnoreCase(letra)) {
                correcto = true;
            }
        }
        return correcto;
    }

    public void onRowSelectAlumno(Alumno alumno) {
        System.out.println("CArgando alumno NIF Before:" + alumno.getNif());
        this.alumno = alumno;
        System.out.println("CArgando alumno NIF After:" + alumno.getNif());
    }

    public String getValorBusqueda() {
        return valorBusqueda;
    }

    public LazyDataModel<Alumno> getListaAlumno() {
        return listaAlumno;
    }

    public void setListaAlumno(LazyDataModel<Alumno> listaAlumno) {
        this.listaAlumno = listaAlumno;
    }

    public void setValorBusqueda(String valorBusqueda) {
        this.valorBusqueda = valorBusqueda;
    }

    public void saveFacturarAlumno() {

        saveFacturarAlumno(fac.getFacalumno());
        if (null != fac.getAlumno()) {
            if (null != this.getAlumno() && fac.getAlumno().getId().equals(this.getAlumno().getId())) {
                alumnoClassPractica = new AlumnoClassPractica();

                if (null != alumno.getId()) {
                    List<AlumnoClassPractica> practicaList = serviceAlunmo.findClassPracticas(alumno.getId());
                    if (CollectionUtils.isNotEmpty(practicaList)) {
                        alumnoClassPractica = practicaList.get(0);
                    }
                }
            }
        }
        fac.init();
    }

    public void saveFacturarAlumno(FacturaAlumno facalumno) {
        boolean goodToGo = true;

        if (null == facalumno) {
            //msgInfoError("El campo \"Profesor\" es requerido");
            goodToGo = false;
            return;
        }

        if (null == facalumno.getFechafactura()) {
            msgInfoError("El campo \"Fecha\" es requerido");
            goodToGo = false;
        }
        if (null == facalumno.getImporte()) {
            msgInfoError("El campo \"Importe\" es requerido");
            goodToGo = false;
        }
//        if(null == facalumno.getFecharegistro()) {
//            msgInfoError("El campo \"Fecha\" es requerido");
//        }
        if (null == fac.getAlumno()) {
            msgInfoError("El campo \"Alumno\" es requerido");
            goodToGo = false;
        }

        if (!goodToGo) {
            return;
        }

        RequestContext context = RequestContext.getCurrentInstance();
        try {
            if (facalumno.getServicio().equals("BTP")
                    || facalumno.getServicio().equals("C")
                    || facalumno.getServicio().equals("D")
                    || facalumno.getServicio().equals("C+E")) {
                facalumno.setIva(0.0);
            } else {
                facalumno.setIva(21.0);
            }
            facalumno.setCliente(usuario.getCliente());
            facalumno.setSeccion(seccion);
            facalumno.setFecharegistro(new Date());
            facalumno.setAlumno(fac.getAlumno());
            fas.save(facalumno);

            fac.setIdFacturaAlumno(fas.getIdFactura());
            //Esta parte esta por definirse

            Movimiento movi = new Movimiento();

            movi.setFecha(new Date());
            movi.setSeccion(seccion);
            movi.setConcepto(facalumno.getServicio());

            movi.setHaber(facalumno.getImporte());
            movi.setIva(facalumno.getIva());
            if (Double.valueOf(21.0).equals(movi.getIva())) {
                movi.setImpIVA(movi.getIva() * movi.getHaber() / 100);
            } else {
                movi.setImpIVA(0.00);
            }
            movi.setCliente(facalumno.getCliente());
            movi.setSeccion(facalumno.getSeccion());
            movi.setTotal(movi.getHaber() + movi.getImpIVA());
            movi.setBc(0.0);
            movimientoService.save(movi);

            msgCambiosGuardados();

            context.addCallbackParam("statusTransaction", true);
            context.addCallbackParam("idFacturaAlumno", fac.getIdFacturaAlumno());
        } catch (Exception e) {
            e.printStackTrace();
            context.addCallbackParam("statusTransaction", false);
            context.addCallbackParam("errorTransaction", "ERROR : " + e);
        }
    }

    public Permisomatriculado getPermisomatriculado() {
        return permisomatriculado;
    }

    public void setPermisomatriculado(Permisomatriculado permisomatriculado) {
        this.permisomatriculado = permisomatriculado;
    }

    public Permisoposee getPermisoposee() {
        return permisoposee;
    }

    public void setPermisoposee(Permisoposee permisoposee) {
        this.permisoposee = permisoposee;
    }

    public DefaultStreamedContent getDc() {
        return dc;
    }

    public void setDc(DefaultStreamedContent dc) {
        this.dc = dc;
    }

    public Date getDiffFecha() {
        return diffFecha;
    }

    public void setDiffFecha(Date diffFecha) {
        this.diffFecha = diffFecha;
    }

    public boolean isTodo() {
        return todo;
    }

    public void setTodo(boolean todo) {
        this.todo = todo;
    }

    /**
     * @return the pdfImprimir
     */
    public String getPdfImprimir() {
        return pdfImprimir;
    }

    /**
     * @param pdfImprimir the pdfImprimir to set
     */
    public void setPdfImprimir(String pdfImprimir) {
        this.pdfImprimir = pdfImprimir;
    }

    public DefaultStreamedContent getDcContract() {
        return dcContract;
    }

    public void setDcContract(DefaultStreamedContent dcContract) {
        this.dcContract = dcContract;
    }

    public AlumnoClassPractica getAlumnoClassPractica() {
        return alumnoClassPractica;
    }

    public void setAlumnoClassPractica(AlumnoClassPractica alumnoClassPractica) {
        this.alumnoClassPractica = alumnoClassPractica;
    }

    public FacturaAlumnoController getFac() {
        return fac;
    }

    public void setFac(FacturaAlumnoController fac) {
        this.fac = fac;
    }
}
